#ifndef _SCIFIFO_H_
#define _SCIFIFO_H_

#include "stdint.h"
/**
 * @file scififo.h
 * @author calm
 * @brief scififo
 * @version 1.1
 * 	scififo_at 锟睫改ｏ拷锟斤拷out锟斤拷始锟斤拷锟斤拷
 * @date 2023-03-03
 *  
 * @copyright Copyright (c) 2023
 * 
 */


#define NO_BUFF     ((void*) 0)

#define TPYE_LEN    uint16_t

#define SCIFIFO(fifo_name)    &fifo_name.scififo




struct scififo_t {
	unsigned int	in;
	unsigned int	out;
	unsigned int	mask;
    unsigned int	type_size;  
    void            *data;  
};

#define DECLARE_SCIFIFO(fifo_name, type, size) struct { \
    struct scififo_t scififo; \
    type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \
} fifo_name

#define INIT_SCIFIFO(fifo) { \
    typeof(&fifo) _tmp = &fifo; \
    struct scififo_t *_scififo = &_tmp->scififo; \
    _scififo->in = 0; \
    _scififo->out = 0; \
    _scififo->mask = sizeof(_tmp->buf) / sizeof(_tmp->buf[0]) - 1; \
    _scififo->data = _tmp->buf; \
    _scififo->type_size = sizeof(*_tmp->buf);\
}

#define scififo_clear(fifo)  _scififo_clear(fifo)
#define scififo_length(fifo) _scififo_length(fifo)

#define scififo_remove(fifo, buf, data_num) _scififo_remove(fifo, buf,  data_num)
#define scififo_append(fifo, buf, data_num) _scififo_append(fifo, buf,  data_num)


#define scififo_at_from_in(fifo, buf, index) _scififo_at_in(fifo, buf, index)
#define scififo_at_from_out(fifo, buf, index)  _scififo_at_out(fifo,  buf, index);



void _scififo_clear(struct scififo_t *);
uint16_t _scififo_length(struct scififo_t *);
uint16_t _scififo_append(struct scififo_t *fifo, const void *buf, uint16_t data_num);
uint16_t _scififo_remove(struct scififo_t *fifo, void *buf, uint16_t data_num);
uint16_t _scififo_at_out(struct scififo_t *fifo, void *buf, uint16_t index);
uint16_t _scififo_at_in(struct scififo_t *fifo, void *buf, uint16_t index);


#endif /* _SCIFIFO_H_ */
